package com.xcc.core.netty.server;

import java.io.InputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.xcc.core.netty.coder.FixedLengthFrameDecoder;
import com.xcc.core.netty.coder.FixedLengthFrameEncoder;
import com.xcc.core.netty.ssl.MyServerSslContextFactory;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public abstract class Server {

    private static final Log logger = LogFactory.getLog(Server.class);
    EventLoopGroup bossGroup = new NioEventLoopGroup(); //bossGroup就是parentGroup，是负责处理TCP/IP连接的
    EventLoopGroup workerGroup = new NioEventLoopGroup(); //workerGroup就是childGroup,是负责处理Channel(通道)的I/O事件
    Channel    mChannel;

    public   void bind(int port) throws Exception {
        ServerBootstrap sb = new ServerBootstrap();
        sb.group(bossGroup, workerGroup)
        .channel(NioServerSocketChannel.class)
        .childOption(ChannelOption.SO_KEEPALIVE, true) //保持长连接
        .childHandler(new ChannelInitializer<SocketChannel>() {  // 绑定客户端连接时候触发操作
            @Override
            protected void initChannel(SocketChannel sh) throws Exception {
              
                getHandles(sh);
                
                sh.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                    //输出流
                    //获取输入流
                    @Override
                    public void channelRead(ChannelHandlerContext ctx, Object msg)
                        throws Exception {
                        getInputStream(ctx,msg);
                    }
                });  

            }
        });
        //绑定监听端口，调用sync同步阻塞方法等待绑定操作完
        ChannelFuture future = sb.bind(port).sync();
     //   mChannel = future.channel();
        if (future.isSuccess()) {
            logger.debug("服务绑定端口："+port);
            System.out.println("服务绑定端口："+port);
        } else {
            logger.debug("服务端启动失败");
            System.out.println("服务端启动失败");
        }
    //    future.channel().closeFuture().sync();
    //    bossGroup.shutdownGracefully();
    //    workerGroup.shutdownGracefully();
    } 

    public abstract InputStream getInputStream(ChannelHandlerContext ctx,Object bs);

    public abstract void getHandles(SocketChannel sh);

    
    public void getOutStream(byte[] bs) {
        mChannel.writeAndFlush(bs);
    }

}


